	//****************************************
	// Author: Mathew Boorman
	// Based on FontGenerator.cs 1.0 by trodoss
	// Copyright (c) 2010
	// See end of file for terms of use.  
    //
    // Generates a spin file with TV_Text compatible font tables
    // i.e. compatible with the Propeller ROM font.
    // These fonts are additional to the ROM font, for the moment modify TV_Text to
    // pass in the address of the character shifted right 6 bits. (/128)
    //
	// On Linux build it with mono using the command "gmcs  -r:System.Drawing FontGenerator16x32.cs"
    // On Windows... TBA from someone who has it.
	//***************************************
	// Version 0.1 - Tech Preview
	// Version 0.3 - (trodoss) Merge with FontGenerator codebase
	using System;
	using System.Collections;
	using System.Drawing;
	using System.Drawing.Imaging;
	using System.Drawing.Drawing2D;
	using System.IO;

	//************** N A M E S P A C E ****************************************
	namespace PropellerUtilities.Font {
		//*********************************************************************
		// FontGenerator Class
		//*********************************************************************	
		public class TVTextWriter {			
			/// <sumary>
			/// Build the static header for the output file
			/// </sumary>		
			private static string BuildHeaderText(int fontChaars) {
				string headerText = "'' Font generated by FontGenerator\n";
				headerText += "'' compatable with TV_Text\n\n";
				headerText += "CON\n\n";
				headerText += "        FONT_CHARS              = "+fontChaars+"\n\n";

				headerText += "PUB GetPtrToFontTable\n\n";

				headerText += "        result                  := @fonttab\n\n";

				headerText += "pub define(c,c0,c1,c2,c3,c4,c5,c6,c7) | p \n";
				headerText += " p:=@fonttab+(c<<3)\n";
				headerText += " byte[p][0]:=c0\n";
				headerText += " byte[p][1]:=c1\n";
				headerText += " byte[p][2]:=c2\n";
				headerText += " byte[p][3]:=c3\n";
				headerText += " byte[p][4]:=c4\n";
				headerText += " byte[p][5]:=c5\n";
				headerText += " byte[p][6]:=c6\n";
				headerText += " byte[p][7]:=c7\n\n";
				headerText += "DAT\n\n";

				return headerText;
			}

			//*********** P U B L I C   F U N C T I O N S  ( M E T H O D S ) ******
			public static void Write (Bitmap bitmap, string outputFileName) {	

					const int FontH = 32;
					const int FontW = 16;
					
					try {
						if ((bitmap.Width%(2*FontW) != 0 || bitmap.Width == 0)) {
							throw new FontException("source bitmap must be multiple of 2 Characters (2x16 pixels) wide.");
						}
						if (bitmap.Height % FontH != 0 || bitmap.Height == 0) {
							throw new FontException("source bitmap must be multiple of one Character (32 pixels) high.");
						}

						int totalCharRows = bitmap.Height / FontH;
						int totalCharCols = bitmap.Width / FontW;
						int totalFontChars = totalCharRows * totalCharCols;

						if (totalFontChars % 2 != 0) {
							throw new FontException("must be an even number of characters (they are interleaved).");
						}

						StreamWriter streamWriter = new StreamWriter(outputFileName);
						streamWriter.Write(BuildHeaderText(totalFontChars));
						streamWriter.WriteLine("fonttab"); 

						// for each PAIR of chars
						for (int charNum=0; charNum < totalFontChars; charNum+=2) {
							int charRow = charNum / totalCharCols;
							int charCol = charNum % totalCharCols;

                            int xOff = charCol * FontW;
                            int yOff = charRow * FontH;

							streamWriter.WriteLine("'pair $" + FontUtilities.ToHexString(charNum) + "  $" + FontUtilities.ToHexString(charNum+1) + "row=" + charRow + " col=" + charCol + " xoff="+ xOff + " yoff=" + yOff ); 

							// now per pixel ROW in Char (pair)							
							for (int pixY = yOff; pixY < yOff + FontH; pixY++) {

								string byteString = "";
								string picString = "";
								string picStringA = "";
								string picStringB = "";

								// for each pixel (pair)
								for (int pixX = xOff; pixX < (xOff + FontW); pixX++) {

									// 1st font char
                  					//Console.WriteLine("pixel x=" + pixX + ", y=" + pixY);
									Color pixelColor = bitmap.GetPixel(pixX, pixY);
									if ((pixelColor.R == 255) && (pixelColor.G == 255) && (pixelColor.B == 255)) {
										picString  += "a";
										picStringA += "#";
										byteString += "1";
									} else {
										picString +=  ".";
										picStringA += ".";
										byteString += "0";
									}

									// 2nd font char
                  					//Console.WriteLine("pixel x=" + (pixX+FontW) + ", y=" + pixY);
									pixelColor = bitmap.GetPixel(pixX+FontW, pixY);
									if ((pixelColor.R == 255) && (pixelColor.G == 255) && (pixelColor.B == 255)) {
										picString  += "b";
										picStringB += "#";
										byteString += "1";
									} else {
										picString +=  ".";
										picStringB += ".";
										byteString += "0";
									}

								}

								// now write the pixel row
								streamWriter.Write ("        byte long %" + byteString + "   ' "
										+ picString + " " + picStringA + " " + picStringB);
								streamWriter.WriteLine("");
							}
					}

					streamWriter.WriteLine("fontab_end ' End of data");

                    // finally add on some padding to allow for alignment of the font tiles.
					// the Tiles must be 64byte (16 Long) aligned.  Since we can't seem to define the location
					// its stored, we allow for padding, and reallign on load.  (Any better way??? BST extension?) 
					streamWriter.WriteLine("");
					streamWriter.WriteLine(" ' space to 64byte tile re-alignment");
					streamWriter.Write("byte long 0");
					for (int pad = 0; pad<15; pad++) {
						streamWriter.Write(", 0");
					}
		
					streamWriter.Close();
					streamWriter = null;
				bitmap = null;
				


			} catch (Exception e) {
				throw new FontException("Error: " + e.ToString());
			}
		}
	}
}

	/*
	+------------------------------------------------------------------------------------------------------------------------------+
	                                                   TERMS OF USE: MIT License                                                                                                              
	+------------------------------------------------------------------------------------------------------------------------------
	Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation     
	files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    
	modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
	is furnished to do so, subject to the following conditions:                                                                   

	The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          
	WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         
	COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   
	ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         
	+------------------------------------------------------------------------------------------------------------------------------+
	 */

